package com.topscomm.mpm.appController;

import com.topscomm.basic.util.Config;
import com.topscomm.basic.util.SQLAdapter;
import com.topscomm.cbo.pojo.CboDeptEntity;
import com.topscomm.cbo.pojo.CboModuleEntity;
import com.topscomm.cbo.pojo.CboPermissionModuleEntity;
import com.topscomm.cbo.pojo.CboRoleEntity;
import com.topscomm.cbo.service.impl.CboDeptService;
import com.topscomm.cbo.service.impl.CboModuleService;
import com.topscomm.cbo.service.impl.CboPermissionModuleService;
import com.topscomm.cbo.service.impl.CboRoleService;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.SpringUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.vo.ResponseResult;
import com.topscomm.tap.common.SessionUserBean;
import com.topscomm.tap.mybatis.MybatisRedisCache;
import com.topscomm.tap.threadlocal.ThreadLocalContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author: chufuying
 * @version: 1.0.0
 * @date: 2021/6/30 8:58
 * @email: chufuying@topscomm.com
 * @JDK: 1.8
 **/
@RestController
@RequestMapping(value = "/app/user", produces = "application/json;charset=UTF-8")
public class AppPermissionController {
    private static final int ADMIN_LEVEL = 9;
    private final CboRoleService cboRoleService;
    private final CboDeptService cboDeptService;
    private final CboPermissionModuleService permissionModuleService;
    private final CboModuleService moduleService;
    @Resource(name = "mybatisRedisTemplate")
    private RedisTemplate<String, Object> redisTemplate;
    // 缓存过期时间(秒)
    private static final int cacheLiveTime = 300;

    @Autowired
    public AppPermissionController(CboRoleService cboRoleService, CboDeptService cboDeptService,
                                   CboPermissionModuleService permissionModuleService, CboModuleService moduleService) {
        this.cboRoleService = cboRoleService;
        this.cboDeptService = cboDeptService;
        this.permissionModuleService = permissionModuleService;
        this.moduleService = moduleService;
    }

    @GetMapping("/permissions")
    public ResponseResult getUserPermissions() {
        // 获取当前登录用户信息
        SessionUserBean userBean = ThreadLocalContext.sessionUserBeanThreadLocal.get();
        Map<String, Object> dataMap = new HashMap<>();

        // 查询角色
        List<CboRoleEntity> roles = cboRoleService.queryRolesByUserId(userBean.getUser().getId());

        // 加载菜单
        List<CboModuleEntity> listModule;
        String rootCode = Config.getInstance().getValue("ModuleRootCode", "") + ","
                + Config.getInstance().getValue("MobileModuleRootCode", "");
        if (userBean.getUser().getAdminlevel() != ADMIN_LEVEL) {
            // 所在的所有部门列表
            CboDeptEntity dept = cboDeptService.queryById("" + userBean.getUser().getDeptid());
            // 查询部门以及上级部门
            String deptUser = "";
            List<Map<String, Object>> list = getAllDeptList();
            for (Map<String, Object> deptMap : list) {
                if (ConvertUtil.convertToString(deptMap.get("code")).length() > 0
                        && ConvertUtil.convertToString(dept.getCode())
                        .startsWith(ConvertUtil.convertToString(deptMap.get("code")))
                        && dept.getOrgid() == ConvertUtil.convertToLong(deptMap.get("orgid"))) {
                    deptUser += "," + ConvertUtil.convertToLong(deptMap.get("id"));
                }
            }
            if (deptUser.startsWith(",")) {
                deptUser = deptUser.substring(1);
            }
            // 权限菜单
            List<CboPermissionModuleEntity> permissions = permissionModuleService.queryUserModules(userBean.getUser().getId(),
                    roles, deptUser);
            List<String> listModuleId = new ArrayList<String>();
            for (int i = 0; permissions != null && i < permissions.size(); i++) {
                CboPermissionModuleEntity per = permissions.get(i);
                if (!listModuleId.contains(ConvertUtil.convertToString(per.getModuleid()))) {
                    listModuleId.add(String.valueOf(per.getModuleid()));
                }
            }
            // 最终显示菜单
            listModule = moduleService.queryModule(listModuleId, rootCode);
        } else {// 管理员
            String[] codes = rootCode.split(",");
            StringBuilder whereSql = new StringBuilder("(");
            for (String code : codes) {
                whereSql.append("code like '").append(code).append("%' or ");
            }
            whereSql = new StringBuilder(whereSql.substring(0, whereSql.length() - 3) + ")");
            listModule = moduleService.queryByWhere(whereSql + " and Enabled=1 order by sortcode,code asc ");
        }
        dataMap.put("roleList", filterRoleList(roles));
        dataMap.put("moduleList", filterModuleList(listModule));
        return ResponseResult.ok(dataMap);
    }

    /**
    * @Description:    获取部门信息
    * @Author:         mengmeng
    * @Date:           2021/12/15 16:08
    * @Version:        1.0
    */
    private List<Map<String, Object>> getAllDeptList() {
        String sql = "enabled=1";
        String key = "alldeptlist" + sql;
        List<Map<String, Object>> list = null;
        Object object = getObject(key);
        if (null == object) {
            List<String> filedList = new ArrayList<String>();
            filedList.add("code");
            filedList.add("orgid");
            filedList.add("id");
            list = cboDeptService.queryMapFieldsByWhere("enabled=1", filedList);
            putObject(key, list);
        }
        else {
            list = (List<Map<String, Object>>) object;
        }
        return list;
    }

    /**
     * @param listModule
     * @return
     * @Title: filterModuleList
     * @author: litianxing
     * @return_type: List<Map < String, Object>>
     * @Description: 过滤手机端权限模块
     */
    private List<Map<String, Object>> filterModuleList(List<CboModuleEntity> listModule) {
        List<Map<String, Object>> result = new ArrayList<>();
        for (CboModuleEntity cboModuleEntity : listModule) {
            // 扩展字段1为手机端编码，扩展字段2为手机端模块名称
            if (cboModuleEntity.getExtendfield1() != null) {
                Map<String, Object> module = new HashMap<>();
                if (cboModuleEntity.getExtendfield2() != null && !"".equals(cboModuleEntity.getExtendfield2())) {
                    module.put("mobileName", cboModuleEntity.getExtendfield2());
                } else {
                    module.put("mobileName", cboModuleEntity.getName());
                }
                module.put("mobileCode", cboModuleEntity.getExtendfield1());
                result.add(module);
            }
        }
        return result;
    }

    /**
     * @param roleList
     * @return
     * @Title: filterRoleList
     * @author: litianxing
     * @return_type: List<Map < String, Object>>
     * @Description: 过滤角色的一些属性
     */
    private List<Map<String, Object>> filterRoleList(List<CboRoleEntity> roleList) {
        List<Map<String, Object>> result = new ArrayList<>();
        if (roleList != null) {
            for (CboRoleEntity cboRoleEntity : roleList) {
                Map<String, Object> role = new HashMap<>();
                role.put("code", cboRoleEntity.getCode());
                role.put("name", cboRoleEntity.getName());
                result.add(role);
            }
        }
        return result;
    }

    public void putObject(Object key, Object value) {
        if (key == null) {
            return;
        }
        String keystring = getKey(key);
        redisTemplate.opsForValue().set(keystring, value, cacheLiveTime, TimeUnit.SECONDS);
    }

    public Object getObject(Object key) {
        if (key == null) {
            return null;
        }
        String keystring = getKey(key);
        return redisTemplate.opsForValue().get(keystring);
    }

    private String getKey(Object key) {
        return "mybatis:" + "cbodeptentity" + ":" + key.toString();
    }
}
